package com.yz.dadatasource.dynamic.config.zookeeper;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import lombok.SneakyThrows;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;

@Configuration
public class ZookeeperConfig extends DefaultListableBeanFactory implements ApplicationContextAware  {

    private static ConfigurableApplicationContext applicationContext;

    public ZooKeeper zooKeeper(){
        ZooKeeper zooKeeper = null;


        try {
            zooKeeper = new ZooKeeper("azyjz.ltd:2181", 5000, new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    // 捕获事件状态
                    if (event.getType() == Event.EventType.None) {
                        if (event.getState() == Event.KeeperState.SyncConnected) {
                            System.out.println("连接成功");
                        } else if (event.getState() == Event.KeeperState.Disconnected) {
                            System.out.println("连接断开!");
                        }else if (event.getState() == Event.KeeperState.Expired){
                            System.out.println("连接超时!");
                            // 超时后服务器端已经将连接释放，需要重新连接服务器端

                            addWatcher();
                        }
                    }
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return zooKeeper;
    }


    public ZooKeeper addWatcher() {
        try {
            ZooKeeper zooKeeper = zooKeeper();
            zooKeeper.exists("/config/url", new Watcher() {
                public void process(WatchedEvent event) {
                    if(event.getType()== Watcher.Event.EventType.NodeDataChanged){

                        DruidDataSource druidDataSource = druidDataSource();
                        DynamicDataSource bean = applicationContext.getBean(DynamicDataSource.class);
                        bean.setDataSource(druidDataSource);
                        System.out.println("==");
                        try {
                            zooKeeper.close();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }


                    }
                }
            });
            return zooKeeper;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
        return null;
    }


    public DruidDataSource druidDataSource(){
        ZooKeeper zooKeeper = addWatcher();
        DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
        try {
            String host = new String(zooKeeper.getData("/config/url",true, null));
            String username = new String(zooKeeper.getData("/config/username",true, null));
            String password = new String(zooKeeper.getData("/config/password",true, null));
            druidDataSource = new DruidDataSource();
            druidDataSource.setUrl(host);
            druidDataSource.setUsername(username);
            druidDataSource.setPassword(password);
        }catch (Exception e){

        }
        return druidDataSource;
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();

        dynamicDataSource.setDataSource(druidDataSource());
        dynamicDataSource.setTargetDataSources(new HashMap<>());
        //dynamicDataSource.setDefaultTargetDataSource(druidDataSource());
        //DynamicDataSource.setDataSource(druidDataSource());
        return dynamicDataSource;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = (ConfigurableApplicationContext )applicationContext;
    }


}
